package com.harmontronics.hanma.paas.paas.domain.app.service;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.harmontronics.hanma.paas.paas.utils.OkHttpUtils;
import lombok.SneakyThrows;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import org.flowable.common.engine.api.delegate.Expression;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.JavaDelegate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.system.ApplicationHome;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.io.File;
import java.util.Map;

/**
 * @author ldb
 */
public class ServiceTaskHttpSupportDelegate implements JavaDelegate {

    private Expression httpServiceId;

    private Expression path;

    private Expression params;

    @Autowired
    private OkHttpClient okHttpClient;

    @Autowired
    private HmHttpRequestDefinitionService hmHttpRequestDefinitionService;

    @SneakyThrows
    @Override
    public void execute(DelegateExecution execution) {

        String httpServiceIdStr = (String) httpServiceId.getValue(execution);
        Long httpServiceId = Long.parseLong(httpServiceIdStr);
        String pathStr = (String) path.getValue(execution);
        String paramsStr = (String) params.getValue(execution);

        String reqUrl = hmHttpRequestDefinitionService.getReqUrl(httpServiceId, pathStr);
        Request.Builder builder = new Request.Builder();
        builder.url(reqUrl);
        ObjectMapper objectMapper = new ObjectMapper();
        ObjectNode rootNode = objectMapper.createObjectNode();
        rootNode.put("processInstanceId", execution.getProcessInstanceId());

        JsonNode extraParamMap = objectMapper.readValue(paramsStr, new TypeReference<JsonNode>() {
        });
        rootNode.set("extParams", extraParamMap);

        Map<String, Object> modelMap = execution.getVariables();
        JsonNode modelNode = objectMapper.convertValue(modelMap, JsonNode.class);
        rootNode.set("model", modelNode);
        MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
        RequestBody requestBody = RequestBody.create(mediaType, objectMapper.writeValueAsString(rootNode));
        builder.post(requestBody);
        String result = OkHttpUtils.execNewCall(okHttpClient, builder.build());
        if (!"ok".equalsIgnoreCase(result)) {
            throw new IllegalArgumentException(result);
        }
    }


    private File getScriptFile(String appUnique) {
        ApplicationHome home = new ApplicationHome(getClass());
        File homeDir = home.getDir();
        File scriptHomeDir = new File(homeDir, "script");
        return new File(scriptHomeDir, appUnique);

    }

    private void executeJavaScript(DelegateExecution execution, String code) throws ScriptException {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("JavaScript");
        engine.put("execution", execution);
        engine.eval(code);
    }
}
